package flish

import (
	emodel "engine/model"
	"math/rand"
	"time"
)

type FishSelector struct {
	fishes      []emodel.MyFlish
	totalWeight int
	prefixSum   []int
	rng         *rand.Rand
}

func NewFishSelector(fishes []emodel.MyFlish) *FishSelector {
	if len(fishes) == 0 {
		return nil
	}

	// 计算总权重和前缀和
	total := 0
	prefixSum := make([]int, len(fishes))

	for i, fish := range fishes {
		total += fish.Gl
		prefixSum[i] = total
	}

	return &FishSelector{
		fishes:      fishes,
		totalWeight: total,
		prefixSum:   prefixSum,
		rng:         rand.New(rand.NewSource(time.Now().UnixNano())),
	}
}

// SelectOne 随机选择一个鱼
func (f *FishSelector) SelectOne() *emodel.MyFlish {
	if len(f.fishes) == 0 {
		return nil
	}

	r := f.rng.Intn(f.totalWeight)

	// 二分查找 O(log n)
	left, right := 0, len(f.prefixSum)-1
	for left < right {
		mid := left + (right-left)/2
		if r < f.prefixSum[mid] {
			right = mid
		} else {
			left = mid + 1
		}
	}

	return &f.fishes[left]
}

// SelectMultiple 选择多个（可重复）
func (f *FishSelector) SelectMultiple(count int) []*emodel.MyFlish {
	if count <= 0 {
		return nil
	}

	result := make([]*emodel.MyFlish, count)
	for i := 0; i < count; i++ {
		result[i] = f.SelectOne()
	}
	return result
}

// SelectMultipleUnique 选择多个不重复的
func (f *FishSelector) SelectMultipleUnique(count int) []*emodel.MyFlish {
	if count <= 0 || len(f.fishes) == 0 {
		return nil
	}

	// 如果请求数量超过总数，返回全部
	if count >= len(f.fishes) {
		result := make([]*emodel.MyFlish, len(f.fishes))
		for i := range f.fishes {
			result[i] = &f.fishes[i]
		}
		return result
	}

	result := make([]*emodel.MyFlish, 0, count)
	selected := make(map[uint64]bool, count)

	for len(result) < count {
		fish := f.SelectOne()
		if !selected[fish.Id] {
			selected[fish.Id] = true
			result = append(result, fish)
		}
	}

	return result
}
